package org.ielse.frame.view;

import java.util.Stack;

import org.ielse.frame.util.BaseUtil;

import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
import android.animation.ValueAnimator;
import android.animation.ValueAnimator.AnimatorUpdateListener;
import android.app.Activity;
import android.content.Context;
import android.graphics.Color;
import android.util.AttributeSet;
import android.util.DisplayMetrics;
import android.view.Gravity;
import android.view.View;
import android.view.WindowManager;
import android.widget.FrameLayout;
import android.widget.LinearLayout;
import android.widget.TextView;

import com.nineoldandroids.view.ViewHelper;

public class TitleLayout extends FrameLayout {

	private int heightSize;

	private final DisplayMetrics outMetrics = new DisplayMetrics();
	private final Stack<TitleContainer> titleContainers = new Stack<TitleContainer>();

	public TitleLayout(Context context) {
		this(context, null);
	}

	public TitleLayout(Context context, AttributeSet attrs) {
		super(context, attrs);
		WindowManager wm = (WindowManager) getContext().getSystemService(Context.WINDOW_SERVICE);
		wm.getDefaultDisplay().getMetrics(outMetrics);

		heightSize = BaseUtil.isScreenVertical((Activity) getContext()) ? (int) (outMetrics.widthPixels * 0.135f)
				: (int) (outMetrics.heightPixels * 0.135f);

		setBackgroundColor(0xf02bbea1);
	}

	@Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
		measureChildren(widthMeasureSpec, heightSize);
		setMeasuredDimension(widthMeasureSpec, heightSize);
	}

	public TitleContainer pushContent(View left, String titleText, View right, boolean anim) {
		return pushContent(left, makeTextTitle(titleText), right, anim);
	}

	/** replace stack top */
	public TitleContainer pushContent(View left, View center, View right, boolean anim) {
		final TitleContainer tc = new TitleContainer(getContext());
		tc.setContent(left, center, right);
		TitleContainer last = null;
		if (!titleContainers.isEmpty()) {
			last = titleContainers.pop();
		}
		titleContainers.push(tc);
		addView(tc);

		final TitleContainer mLast = last;
		if (anim) {
			ValueAnimator animator = ValueAnimator.ofFloat(0, 1).setDuration(300);
			animator.addUpdateListener(new AnimatorUpdateListener() {
				@Override public void onAnimationUpdate(ValueAnimator animation) {
					float value = (Float) animation.getAnimatedValue();
					if (mLast != null) {
						ViewHelper.setAlpha(mLast.layLeft, 1 - value);
						ViewHelper.setAlpha(mLast.layCenter, 1 - value);
						ViewHelper.setTranslationX(mLast.layCenter, -getWidth() / 6 * value);
						ViewHelper.setAlpha(mLast.layRight, 1 - value);
					}
					ViewHelper.setAlpha(tc.layLeft, value);
					ViewHelper.setAlpha(tc.layCenter, value);
					ViewHelper.setTranslationX(tc.layCenter, getWidth() / 6 * (1 - value));
					ViewHelper.setAlpha(tc.layRight, value);
				}
			});
			animator.addListener(new AnimatorListenerAdapter() {
				@Override public void onAnimationEnd(Animator animation) {
					removeView(mLast);
				}
			});
			animator.start();
		}
		else {
			removeView(mLast);
		}

		return tc;
	}

	public TitleContainer pushNewContent(View left, String titleText, View right, boolean anim) {
		return pushNewContent(left, makeTextTitle(titleText), right, anim);
	}

	public TitleContainer pushNewContent(View left, View center, View right, boolean anim) {
		final TitleContainer tc = new TitleContainer(getContext());
		tc.setContent(left, center, right);

		TitleContainer last = null;
		if (!titleContainers.isEmpty()) {
			last = titleContainers.peek();
		}
		final TitleContainer mLast = last;
		titleContainers.push(tc);
		addView(tc);

		if (anim) {
			ValueAnimator animator = ValueAnimator.ofFloat(0, 1).setDuration(300);
			animator.addUpdateListener(new AnimatorUpdateListener() {
				@Override public void onAnimationUpdate(ValueAnimator animation) {
					float value = (Float) animation.getAnimatedValue();
					if (mLast != null) {
						ViewHelper.setAlpha(mLast.layLeft, 1 - value);
						ViewHelper.setAlpha(mLast.layCenter, 1 - value);
						ViewHelper.setTranslationX(mLast.layCenter, -getWidth() / 6 * value);
						ViewHelper.setAlpha(mLast.layRight, 1 - value);
					}
					ViewHelper.setAlpha(tc.layLeft, value);
					ViewHelper.setAlpha(tc.layCenter, value);
					ViewHelper.setTranslationX(tc.layCenter, getWidth() / 6 * (1 - value));
					ViewHelper.setAlpha(tc.layRight, value);
				}
			});
			animator.addListener(new AnimatorListenerAdapter() {
				@Override public void onAnimationEnd(Animator animation) {
					if (mLast != null) {
						mLast.setVisibility(View.GONE);
					}
				}
			});
			animator.start();
		}
		else {
			last.setVisibility(View.GONE);
			final float value = 1;
			ViewHelper.setAlpha(last.layLeft, 1 - value);
			ViewHelper.setAlpha(last.layCenter, 1 - value);
			ViewHelper.setTranslationX(last.layCenter, -getWidth() / 6 * value);
			ViewHelper.setAlpha(last.layRight, 1 - value);
		}

		return tc;
	}

	public View popToLastContent() {
		return popToLastContent(true);
	}

	public View popToLastContent(boolean anim) {
		if (titleContainers.size() < 2) {
			// Not enough item
			return null;
		}
		final TitleContainer curr = titleContainers.pop();
		final float currLayLeftAlpha = curr.layLeft.getAlpha();
		final float currLayCenterAlpha = curr.layCenter.getAlpha();
		final float currLayCenterTranslateX = curr.layCenter.getTranslationX();
		final float currLayRightAlpha = curr.layRight.getAlpha();
		final TitleContainer last = titleContainers.peek();
		final float lastLayLeftAlpha = last.layLeft.getAlpha();
		final float lastLayCenterAlpha = last.layCenter.getAlpha();
		final float lastLayCenterTranslateX = last.layCenter.getTranslationX();
		final float lastLayRightAlpha = last.layRight.getAlpha();

		if (anim) {
			ValueAnimator animator = ValueAnimator.ofFloat(0, 1).setDuration(300);
			animator.addUpdateListener(new AnimatorUpdateListener() {
				@Override public void onAnimationUpdate(ValueAnimator animation) {
					float value = (Float) animation.getAnimatedValue();
					ViewHelper.setAlpha(curr.layLeft, currLayLeftAlpha * (1 - value));
					ViewHelper.setAlpha(curr.layCenter, currLayCenterAlpha * (1 - value));
					ViewHelper
							.setTranslationX(curr.layCenter, currLayCenterTranslateX + (getWidth() / 6 - currLayCenterTranslateX) * value);
					ViewHelper.setAlpha(curr.layRight, currLayRightAlpha * (1 - value));

					ViewHelper.setAlpha(last.layLeft, lastLayLeftAlpha + (1 - lastLayLeftAlpha) * value);
					ViewHelper.setAlpha(last.layCenter, lastLayCenterAlpha + (1 - lastLayLeftAlpha) * value);
					ViewHelper.setTranslationX(last.layCenter, lastLayCenterTranslateX * (1 - value));
					ViewHelper.setAlpha(last.layRight, lastLayRightAlpha + (1 - value));
				}
			});
			animator.addListener(new AnimatorListenerAdapter() {
				@Override public void onAnimationEnd(Animator animation) {
					removeView(curr);
				}
			});
			animator.start();
			last.setVisibility(View.VISIBLE);
		}
		else {
			removeView(curr);
			last.setVisibility(View.VISIBLE);
		}

		return last;
	}

	public void returnToCurrentContent() {
		if (titleContainers.size() < 2) {
			// Not enough item
			return;
		}

		final TitleContainer curr = titleContainers.get(titleContainers.size() - 1);
		final float currLayLeftAlpha = curr.layLeft.getAlpha();
		final float currLayCenterAlpha = curr.layCenter.getAlpha();
		final float currLayCenterTranslateX = curr.layCenter.getTranslationX();
		final float currLayRightAlpha = curr.layRight.getAlpha();
		final TitleContainer last = titleContainers.get(titleContainers.size() - 2);
		final float lastLayLeftAlpha = last.layLeft.getAlpha();
		final float lastLayCenterAlpha = last.layCenter.getAlpha();
		final float lastLayCenterTranslateX = last.layCenter.getTranslationX();
		final float lastLayRightAlpha = last.layRight.getAlpha();

		ValueAnimator animator = ValueAnimator.ofFloat(0, 1).setDuration(300);
		animator.addUpdateListener(new AnimatorUpdateListener() {
			@Override public void onAnimationUpdate(ValueAnimator animation) {
				float value = (Float) animation.getAnimatedValue();
				// setToLastAnimationProgress(progress);
				ViewHelper.setAlpha(curr.layLeft, currLayLeftAlpha + (1 - currLayLeftAlpha) * value);
				ViewHelper.setAlpha(curr.layCenter, currLayCenterAlpha + (1 - currLayCenterAlpha) * value);
				ViewHelper.setTranslationX(curr.layCenter, currLayCenterTranslateX * (1 - value));
				ViewHelper.setAlpha(curr.layRight, currLayRightAlpha + (1 - currLayRightAlpha) * value);

				ViewHelper.setAlpha(last.layLeft, lastLayLeftAlpha * (1 - value));
				ViewHelper.setAlpha(last.layCenter, lastLayCenterAlpha * (1 - value));
				ViewHelper.setTranslationX(last.layCenter, lastLayCenterTranslateX + (-getWidth() / 6 - lastLayCenterTranslateX) * value);
				ViewHelper.setAlpha(last.layRight, lastLayRightAlpha * (1 - value));
			}
		});
		animator.addListener(new AnimatorListenerAdapter() {
			@Override public void onAnimationEnd(Animator animation) {
				titleContainers.get(titleContainers.size() - 2).setVisibility(View.GONE);
			}
		});
		animator.start();
	}

	public void setToLastAnimationProgress(float progress) {
		if (titleContainers.size() < 2) {
			// Not enough item
			return;
		}

		final TitleContainer curr = titleContainers.get(titleContainers.size() - 1);
		final TitleContainer last = titleContainers.get(titleContainers.size() - 2);
		last.setVisibility(View.VISIBLE);

		float value = progress;
		ViewHelper.setAlpha(curr.layLeft, 1 - value);
		ViewHelper.setAlpha(curr.layCenter, 1 - value);
		ViewHelper.setTranslationX(curr.layCenter, getWidth() / 6 * value);
		ViewHelper.setAlpha(curr.layRight, 1 - value);

		ViewHelper.setAlpha(last.layLeft, value);
		ViewHelper.setAlpha(last.layCenter, value);
		ViewHelper.setTranslationX(last.layCenter, -getWidth() / 6 * (1 - value));
		ViewHelper.setAlpha(last.layRight, value);
	}

	private View makeTextTitle(String text) {
		TextView txTitle = new TextView(getContext());
		FrameLayout.LayoutParams lp = new FrameLayout.LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
		lp.gravity = Gravity.CENTER;
		txTitle.setLayoutParams(lp);
		txTitle.setTextSize(18);
		txTitle.setText(text);
		txTitle.setTextColor(Color.WHITE);
		return txTitle;
	}

	class TitleContainer extends LinearLayout {
		FrameLayout layCenter, layLeft, layRight;

		public TitleContainer(Context context) {
			super(context);
			setOrientation(LinearLayout.HORIZONTAL);
			FrameLayout.LayoutParams tcLp = new FrameLayout.LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT);
			tcLp.gravity = Gravity.CENTER_VERTICAL;
			setLayoutParams(tcLp);

			LinearLayout.LayoutParams lpLeft = new LinearLayout.LayoutParams(0, LayoutParams.MATCH_PARENT);
			lpLeft.weight = 1;
			layLeft = new FrameLayout(context);
			layLeft.setLayoutParams(lpLeft);
			addView(layLeft);
			layCenter = new FrameLayout(context);
			LinearLayout.LayoutParams lpCenter = new LinearLayout.LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.MATCH_PARENT);
			layCenter.setLayoutParams(lpCenter);
			addView(layCenter);
			LinearLayout.LayoutParams lpRight = new LinearLayout.LayoutParams(0, LayoutParams.MATCH_PARENT);
			lpRight.weight = 1;
			layRight = new FrameLayout(context);
			layRight.setLayoutParams(lpRight);
			addView(layRight);
		}

		public void setContent(View left, View center, View right) {
			if (left != null) layLeft.addView(left);
			if (center != null) layCenter.addView(center);
			if (right != null) layRight.addView(right);
		}
	}

}
